package cn.tedu.straw.portal.controller;


import cn.tedu.straw.portal.dto.PostQuestionDTO;
import cn.tedu.straw.portal.ex.*;
import cn.tedu.straw.portal.security.LoginUserInfo;
import cn.tedu.straw.portal.service.IQuestionService;
import cn.tedu.straw.portal.util.R;
import cn.tedu.straw.portal.vo.QuestionDetailVO;
import cn.tedu.straw.portal.vo.QuestionListItemVO;
import cn.tedu.straw.portal.vo.QuestionSimpleVO;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author tedu.cn
 * @since 2020-11-11
 */
@RestController
@RequestMapping("/portal/question")
@Slf4j
public class QuestionController {

    @Autowired
    IQuestionService questionService;

    // http://localhost:8080/portal/question/post?title=TestTitle2&content=TestContent2&tagIds=1&tagIds=3&tagIds=15&teacherIds=2&teacherIds=4&teacherIds=5
    @RequestMapping("/post")
    public R<Void> post(@Valid PostQuestionDTO postQuestionDTO, BindingResult bindingResult,
                        @AuthenticationPrincipal LoginUserInfo loginUserInfo) {
        log.debug("发布问题，客户端提交的数据：{}", postQuestionDTO);
        log.debug("发布问题，当前登录的用户信息：{}", loginUserInfo);

        if (bindingResult.hasErrors()) {
            String errorMessage = bindingResult.getFieldError().getDefaultMessage();
            throw new InvalidParameterException(errorMessage);
        }

        Integer userId = loginUserInfo.getUserId();
        String userNickName = loginUserInfo.getNickName();
        questionService.post(postQuestionDTO, userId, userNickName);
        return R.ok();
    }

    @Value("${project.post-question.upload-image.base-dir}")
    String uploadImageBaseDir;
    @Value("${project.post-question.upload-image.max-file-size}")
    int maxFileSize;
    @Value("${project.post-question.upload-image.file-types}")
    public List<String> fileTypes;

    // http://localhost:8080/portal/question/image/upload
    @PostMapping("/image/upload")
    public R<String> uploadImage(MultipartFile file) {
        // 检查上传的文件是否为空
        if (file.isEmpty()) {
            throw new FileEmptyException("上传图片失败！请选择有效的文件！");
        }

        // 判断上传的文件大小是否超出了限制
        if (file.getSize() > maxFileSize) {
            throw new FileSizeException("上传图片失败！不允许上传超过" + maxFileSize/1024/1024 + "MB的图片！");
        }

        // 判断上传的文件类型是否超出了限制，允许：image/jpeg、image/png、image/bmp
        if (!fileTypes.contains(file.getContentType())) {
            throw new FileTypeException("上传图片失败！上传的文件类型超出了限制！允许上传的文件类型有：" + fileTypes);
        }

        // 保存文件的子级文件夹
        LocalDateTime now = LocalDateTime.now();
        String subDir = DateTimeFormatter.ofPattern("yyyy/MM").format(now);
        // 保存文件的文件夹
        File parent = new File(uploadImageBaseDir, subDir);
        if (!parent.exists()) {
            parent.mkdirs();
        }

        // 保存文件的文件名
        String filename = System.currentTimeMillis() + "-" + System.nanoTime();
        // 保存文件的扩展名
        String originalFilename = file.getOriginalFilename();
        int beginIndex = originalFilename.lastIndexOf(".");
        String suffix = originalFilename.substring(beginIndex);
        // 保存文件的文件全名
        String child = filename + suffix;

        // 执行保存
        File dest = new File(parent, child);
        try {
            file.transferTo(dest);
        } catch (IllegalStateException e) {
            throw new FileStateException("上传图片失败！请检查上传的文件是否有效！");
        } catch (IOException e) {
            throw new FileUploadIOException("上传图片失败！服务器忙，请稍后再次尝试！");
        }

        // 图片路径
        String url = "http://localhost:8080/" + subDir + "/" + child;
        System.out.println("\tURL >>> " + url);

        //  返回
        return R.ok(url);
    }

    // http://localhost:8080/portal/question/most-hits
    @GetMapping("/most-hits")
    public R<List<QuestionSimpleVO>> getMostHitsList() {
        return R.ok(questionService.getMostHitsList());
    }

    // http://localhost:8080/portal/question/my?page=1
    @GetMapping("/my")
    public R<PageInfo<QuestionListItemVO>> getMyQuestions(Integer page, @AuthenticationPrincipal LoginUserInfo loginUserInfo) {
        Integer userId = loginUserInfo.getUserId();
        PageInfo<QuestionListItemVO> pageInfo = questionService.getMyQuestions(userId, page);
        return R.ok(pageInfo);
    }

    // http://localhost:8080/portal/question/100
    @GetMapping("/{questionId}")
    public R<QuestionDetailVO> getDetail(@PathVariable("questionId") Integer questionId) {
        return R.ok(questionService.getDetail(questionId));
    }

}
